package com.samsung.sds.ssa.jsca.editor;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.jface.text.rules.BufferedRuleBasedScanner;
import org.eclipse.jface.text.rules.EndOfLineRule;
import org.eclipse.jface.text.rules.IRule;
import org.eclipse.jface.text.rules.IToken;
import org.eclipse.jface.text.rules.MultiLineRule;
import org.eclipse.jface.text.rules.SingleLineRule;
import org.eclipse.jface.text.rules.Token;
import org.eclipse.jface.text.rules.WhitespaceRule;

/**
 * Scanner for detecting syntactic elements: comments, strings, classes,
 * functions
 * 
 */
public class JSSyntaxScanner extends BufferedRuleBasedScanner {
	public final static String JS_DEFAULT = "__js_default";
	public final static String JS_COMMENT = "__js_comment";
	public final static String JS_FUNCTION = "__js_function";
	public final static String JS_STRING = "__js_string";
	public final static String JS_MEMBER = "__js_member";
	public final static String JS_KEYWORD = "__js_keyword";
	public final static String JS_IMPORT= "__js_import";
	public final static String HTML_TAG = "__html_tag";
	
	public final static IToken TOKEN_STRING = new Token(JS_STRING);
	public final static IToken TOKEN_COMMENT = new Token(JS_COMMENT);
	public final static IToken TOKEN_DEFAULT = new Token(JS_DEFAULT);
	public final static IToken TOKEN_FUNCTION = new Token(JS_FUNCTION);
	public final static IToken TOKEN_MEMBER = new Token(JS_MEMBER);
	public final static IToken TOKEN_KEYWORD = new Token(JS_KEYWORD);
	public final static IToken TOKEN_IMPORT= new Token(JS_IMPORT);
	public final static IToken TOKEN_TAG = new Token(HTML_TAG);
	/**
	 * String for detecting member declarations.
	 */ 
	private static String memberToken = ".prototype";

	/**
	 * Creates a new JSSyntaxScanner object.
	 */
	@SuppressWarnings({"rawtypes", "unchecked"})
	public JSSyntaxScanner() {
		List rules = new ArrayList();

		rules.add(new MultiLineRule("/*", "*/", TOKEN_COMMENT));
		rules.add(new EndOfLineRule("//", TOKEN_COMMENT));
		rules.add(new SingleLineRule("\"", "\"", TOKEN_STRING, '\\'));
		rules.add(new SingleLineRule("'", "'", TOKEN_STRING, '\\'));
		rules.add(new SingleLineRule("<script ", "</script>", TOKEN_IMPORT, '\\'));
		rules.add(new TagRule(TOKEN_TAG));
		rules.add(new WhitespaceRule(new JSWhitespaceDetector()));

		rules.add(new MultiLineRule("function(", ")", TOKEN_FUNCTION));
		rules.add(new MultiLineRule("function ", ")", TOKEN_FUNCTION));
		
		PredicateWordRule wordRule = new PredicateWordRule(new JSWordDetector(), TOKEN_DEFAULT, JSPartitionScanner.keywordTokens, TOKEN_KEYWORD);
		wordRule.addWords(JSPartitionScanner.constantTokens, TOKEN_KEYWORD);
		// rules.add(new WordRule(new JAVASCRIPTWordDetector(), TOKEN_DEFAULT));
		rules.add(wordRule);
		rules.add(new PredicateWordRule(new JSReferenceDetector(), memberToken, TOKEN_MEMBER));
		
		setRuleList(rules);
	}

	/**
	 * set the rule list
	 * 
	 * @param rules
	 */
	@SuppressWarnings({"rawtypes", "unchecked"})
	private void setRuleList(List rules) {
		IRule[] result = new IRule[rules.size()];
		rules.toArray(result);
		setRules(result);
	}
}